package com.ruoyi.StarStudio.Controller;

import com.github.pagehelper.PageInfo;
import com.ruoyi.StarStudio.MQTT.EmqClient;
import com.ruoyi.StarStudio.MQTT.QosEnum;
import com.ruoyi.StarStudio.Utils.QueryPageUtils;
import com.ruoyi.StarStudio.Domain.*;
import com.ruoyi.StarStudio.Service.DeviceService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

@SuppressWarnings("rawtypes")
@RestController
@RequestMapping("/devices")
public class DeviceController {

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private EmqClient emqClient;

    /**
     * 获取全部设备信息
     * @return 结果对象 Result
     */
    @GetMapping
    public Result getAll(){
        List<Device> deviceList;
        try {
            deviceList = deviceService.getAll();
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(HttpStatusCode.ERROR, MessageConstant.DEVICE_QUERY_FAIL);
        }
        return new Result(HttpStatusCode.SUCCESS, MessageConstant.DEVICE_QUERY_SUCCESS, deviceList);
    }

    /**
     * 导出设备信息到 Excel表格
     * @param response HTTP响应对象
     * @param device 设备对象
     */
    @Log(title = "设备管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Device device) {
        List<Device> list = deviceService.getList(device);
        ExcelUtil<Device> util = new ExcelUtil<>(Device.class);
        util.exportExcel(response, list, "设备数据");
    }

    /**
     * 从 Excel表格导入设备数据
     * @param file 文件对象
     * @param updateSupport 是否支持更新 开关
     * @return 若依自带的结果对象
     * @throws Exception 异常
     */
    @Log(title = "设备管理", businessType = BusinessType.IMPORT)
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
        ExcelUtil<Device> util = new ExcelUtil<>(Device.class);
        List<Device> deviceList = util.importExcel(file.getInputStream());
        String message = deviceService.importDevice(deviceList, updateSupport);
        return AjaxResult.success(message);
    }

    /**
     * 导入设备数据 Excel模板
     * @param response HTTP响应
     */
    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) {
        ExcelUtil<Device> util = new ExcelUtil<>(Device.class);
        util.importTemplateExcel(response, "设备数据");
    }

    /**
     * 通过设备ID获取设备信息
     * @param deviceId 设备ID
     * @return 结果对象Result
     */
    @GetMapping("/{deviceId}")
    public Result getById(@PathVariable int deviceId){
        Device deviceById;
        try {
            deviceById = deviceService.getById(deviceId);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(HttpStatusCode.ERROR, MessageConstant.DEVICE_QUERY_FAIL);
        }
        return new Result(HttpStatusCode.SUCCESS, MessageConstant.DEVICE_QUERY_SUCCESS, deviceById);
    }

    /**
     * 分页获取设备信息
     * @param device 设备对象
     * @return 分页结果对象 PageResult
     */
    @GetMapping("/page")
    public PageResult getList(Device device){
        QueryPageUtils.startPage();
        List<Device> deviceList;
        PageInfo pageInfo;
        try {
            deviceList = deviceService.getList(device);
            pageInfo = new PageInfo<>(deviceList);
        } catch (Exception e) {
            e.printStackTrace();
            return new PageResult(HttpStatusCode.ERROR, MessageConstant.DEVICE_QUERY_FAIL);
        }
        return new PageResult(HttpStatusCode.SUCCESS, pageInfo.getTotal(), MessageConstant.DEVICE_QUERY_SUCCESS, deviceList);
    }

    /**
     * 新增一台设备
     * @param device 设备对象
     * @param zoneId 地块ID
     * @return 结果对象
     */
    @PostMapping("/{zoneId}")
    public Result add(@RequestBody Device device, @PathVariable int zoneId) {
        try {
            device.setZone_id(zoneId);
            device.setDevice_updateTime(new Timestamp(new Date().getTime()));
            deviceService.add(device,zoneId);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(HttpStatusCode.ERROR, MessageConstant.DEVICE_ADD_FAIL);
        }
        return new Result(HttpStatusCode.SUCCESS, MessageConstant.DEVICE_ADD_SUCCESS);
    }

    /**
     * 更新地块信息
     * @param device 设备对象
     * @return 结果对象
     */
    @PutMapping
    public Result update(@RequestBody Device device){
        try {
            device.setDevice_updateTime(new Timestamp(new Date().getTime()));
            deviceService.update(device);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(HttpStatusCode.ERROR, MessageConstant.DEVICE_UPDATE_FAIL);
        }
        return new Result(HttpStatusCode.SUCCESS, MessageConstant.DEVICE_UPDATE_SUCCESS);
    }

    /**
     * 根据 id 删除一个设备
     * @param deviceId 设备ID
     * @return 结果对象
     */
    @DeleteMapping("/{deviceId}")
    public Result delete(@PathVariable Integer deviceId){
        try {
            deviceService.delete(deviceId);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(HttpStatusCode.ERROR, MessageConstant.DEVICE_DELETE_FAIL);
        }
        return new Result(HttpStatusCode.SUCCESS, MessageConstant.DEVICE_DELETE_SUCCESS);
    }

    /**
     * 下发喷洒系统开关指令
     * @param flag 开关标识符
     * @return Result
     */
    @PostMapping("/SpraySwitch")
    public Result SpraySystemSwitch(@RequestParam("flag") boolean flag){
        try {
            emqClient.publish("SpraySystemSwitch",flag + "", QosEnum.Qos2,false);
        } catch (Exception e) {
            e.printStackTrace();
            if (flag){
                return new Result(HttpStatusCode.ERROR,MessageConstant.SEND_OPEN_ORDER_FAIL);
            }
            return new Result(HttpStatusCode.ERROR,MessageConstant.SEND_CLOSE_ORDER_FAIL);
        }
        if (flag){
            return new Result(HttpStatusCode.SUCCESS,MessageConstant.SEND_OPEN_ORDER_SUCCESS);
        }
        return new Result(HttpStatusCode.SUCCESS,MessageConstant.SEND_CLOSE_ORDER_SUCCESS);
    }
}